#include "stdafx.h"
#include "connection.h"

#include "SqlHandle.h"
#include "..\Win32\Event.h"
#include "..\Win32\ThreadpoolWait.h"

namespace Otl { namespace Sql
{

Connection::Connection(_In_z_ const wchar_t * const connectionString)
{
	auto env = sql_handle{ SQL_HANDLE_ENV };
	auto error = ::SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, reinterpret_cast<SQLPOINTER>(SQL_OV_ODBC3_80), SQL_IS_INTEGER);

	auto connect = sql_handle{ SQL_HANDLE_DBC, env };
	error = ::SQLSetConnectAttrW(connect, SQL_ATTR_ASYNC_DBC_FUNCTIONS_ENABLE, reinterpret_cast<SQLPOINTER>(SQL_ASYNC_DBC_ENABLE_ON), SQL_IS_INTEGER);

	auto callback = []()
	{
	};
	Win32::CThreadpoolWait threadPool { callback };
	auto connectComplete = Win32::CEvent{};
	threadPool.Set(connectComplete);

	error = ::SQLSetConnectAttrW(connect, SQL_ATTR_ASYNC_DBC_EVENT, connectComplete.Handle(), SQL_IS_POINTER);

	error = ::SQLDriverConnectW(connect,
	                            nullptr,
	                            const_cast<wchar_t *>(connectionString),
	                            SQL_NTS,
	                            nullptr,
	                            0,
	                            nullptr,
	                            SQL_DRIVER_NOPROMPT);

	::Sleep(5000);

	RETCODE asyncResult;
	error = ::SQLCompleteAsync(SQL_HANDLE_DBC, connect, &asyncResult);

	wchar_t state[6];
	SQLINTEGER nativeError;
	wchar_t errorMsg[256];
	SQLSMALLINT errorMsgSize = _countof(errorMsg);
	error = ::SQLGetDiagRecW(SQL_HANDLE_DBC, connect, 1, state, &nativeError, errorMsg, errorMsgSize, &errorMsgSize);

	SQLUINTEGER info;
	error = ::SQLGetInfoW(connect, SQL_ASYNC_NOTIFICATION, &info, sizeof(info), nullptr);
}

concurrency::task<void> Connection::Open()
{
	auto tce = concurrency::task_completion_event<void>{};
	tce.set();

	auto task = concurrency::task<void>{tce};

	return task;
}

}
}